package initialize

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/google/uuid"
	"mine-info-server/global"
	"mine-info-server/infra/database/mysql/common-context/message/po"
	"mine-info-server/utils/consts"
	"strconv"
	"time"

	"github.com/go-redis/redis/v8"
	"go.uber.org/zap"
)

func Redis() {
	redisCfg := global.GVA_CONFIG.Redis
	rdb := redis.NewClient(&redis.Options{
		Addr:     redisCfg.Addr,
		Password: redisCfg.Password, // no password set
		DB:       redisCfg.DB,       // use default DB
	})
	//rdb := redis.NewFailoverClusterClient(&redis.FailoverOptions{
	//	MasterName:    "mymaster",
	//	SentinelAddrs: []string{":16379", ":16380", ":16381"},
	//})
	pong, err := rdb.Ping(context.Background()).Result()
	if err != nil {
		global.GVA_LOG.Error("redis connect ping failed, err:", zap.Error(err))
	} else {
		global.GVA_LOG.Info("redis connect ping response:", zap.String("pong", pong))
		global.GVA_REDIS = rdb
	}
}

// 启动两个处理队列的协程
func InitMsgConsumer() {
	ctx := context.Background()
	// 用于将延时队列消息放入即时队列中
	go func() {
		for {
			// 每秒轮询一次，将到时的消息捞到即时队列
			// todo 这里先处理一条，后面变成多条
			time.Sleep(time.Second)
			// 拿到jobID
			strings, err := global.GVA_REDIS.ZRangeByScore(ctx, consts.PlanTimeoutDelayQueue, &redis.ZRangeBy{
				Min:    "-inf",
				Max:    strconv.Itoa(int(time.Now().Unix())),
				Offset: 0,
				Count:  1,
			}).Result()
			if err != nil {
				fmt.Printf("发送错误:%v", err)
			}
			if len(strings) != 0 {
				global.GVA_REDIS.LPush(ctx, consts.PlanTimeoutReadyQueue, strings[0])
			}
		}
	}()

	// 用于处理即时队列消息
	go func() {
		for {
			// 获取JobID
			result, err := global.GVA_REDIS.BRPop(ctx, 0, consts.PlanTimeoutReadyQueue).Result()
			if err != nil {
				continue
			}
			global.GVA_REDIS.ZRem(ctx, consts.PlanTimeoutDelayQueue, result[1]) // 消息入库后将延时队列的消息删除
			// 找到对应的元信息
			jobJson, err := global.GVA_REDIS.Get(ctx, result[1]).Result()
			if err != nil {
				continue
			}
			var job *global.MsgJob
			_ = json.Unmarshal([]byte(jobJson), &job)
			entity := &po.RemindMsg{
				MsgId:      uuid.New().String(),
				Content:    job.Body,
				UserId:     job.UserId,
				CreateTime: time.Now().Format("2006-01-02 15:04:05"),
				IsRead:     1,
			}
			// 这里如果报错就会丢消息
			err = global.GVA_DB.Create(&entity).Error
			if err != nil {
				fmt.Println(err)
			}
			// 执行完后处理jobpool数据
			global.GVA_REDIS.Del(ctx, result[1])
		}
	}()
}
